package com.anda.jsu.yangsp.core.persistence;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.stereotype.Repository;

import com.anda.jsu.yangsp.core.persistence.generic.HibernateDaoSupportBean;
import com.anda.jsu.yangsp.core.view.util.ConvertEntityToView;
import com.anda.jsu.yangsp.core.view.util.PageModel;

/**
 * 
 * @author xiaolu
 * @since 2012-12-06
 *
 */
@Repository("basicDao")
public class BasicDaoImpl<T> extends HibernateDaoSupportBean implements IBasicDao<T> {

	public int countBySQL(String sql) {
		SQLQuery query = this.getSession().createSQLQuery(sql);
		query.addScalar("count", null);
		BigDecimal result = (BigDecimal) query.uniqueResult();
		return result.intValue();
	}

	public void delete(T t) {
		this.getHibernateTemplate().delete(t);
	}

	public void deleteAll(Collection<T> entities) {
		this.getHibernateTemplate().deleteAll(entities);
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> findPageBySQL(final String sql, final Boolean isPage, final int start, final int limit) {
		List<Object[]> list = this.getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createQuery(sql);
				if(isPage){
					query.setFirstResult(start).setMaxResults(limit);
				}
				return query.list();
			}
		});
		return list;
	}

	public T save(T t) {
		this.getHibernateTemplate().save(t);
		return t;
	}

	public T saveOrUpdate(T t) {
		this.getHibernateTemplate().saveOrUpdate(t);
		return t;
	}

	public void saveOrUpdateAll(Collection<T> entities) {
		this.getHibernateTemplate().saveOrUpdateAll(entities);
	}

	public T selectById(Class<T> clazz, Serializable entityId) {
		T t = getHibernateTemplate().get(clazz, entityId);
		return t;
	}

	@SuppressWarnings("unchecked")
	public PageModel<T> selectByPage(final String entityName, final int pageNo, final int pageSize) {
		PageModel<T> pageModel = new PageModel<T>();
		List<T> list = this.getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createQuery("from " + entityName);
				query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize);
				return query.list();
			}
		});
		pageModel.setPageData(list);
		pageModel.setCurrentPage(pageNo);
		pageModel.setPageSize(pageSize);
		pageModel.setTotalCount(this.selectTotalCount(entityName));
		return null;
	}

	public Long selectCountBySelectSQL(String selectSQL) {
		return null;
	}

	public List<T> selectMaxTs(String entityName) {
		return null;
	}

	public List<T> selectSmallTs(String entityName) {
		return null;
	}

	public Long selectTotalCount(String entityName) {
		return (Long) this.getSession().createQuery("select count(1) from " + entityName).uniqueResult();
	}

	public T update(T t) {
		this.getHibernateTemplate().update(t);
		return t;
	}

	@SuppressWarnings("unchecked")
	public List<T> list(final PageModel<T> view) {
		String typeName = ConvertEntityToView.getDeclaredType(this);//获取泛型类型
		final String HQL = "from " + typeName + " t where 1=1";
		final String COUNTHQL = "select count(t.*) from " + typeName + " t where 1=1";
		
		List<T> list = getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(HQL);
				if(view.isPage()){
					query.setFirstResult((view.getCurrentPage() - 1) * view.getPageSize())
							.setMaxResults(view.getPageSize());
				}
				List<T> list = query.list();
				if(view.isPage()){
					query = session.createQuery(COUNTHQL);
					Long totalCount = (Long) query.uniqueResult();
					view.setTotalCount(totalCount);
					view.setTotalPage(totalCount);
				}
				return list;
			}
		});
		return list;
	}

}
